/**
 * MIT License
 * 
 * Copyright (c) 2017 CaiDongyu
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.tunnel.server.udp;
  
import com.tunnel.common.constant.Constant;
import com.tunnel.common.tunnel.TunnelDataSenderManager;
import com.tunnel.common.udp.UdpBaseHandler;
import com.tunnel.server.udp.UdpClientManager.UdpClient;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.AttributeKey;  
 
/**
 * 只负责udp接收数据
 */
public class UdpServerHandler extends UdpBaseHandler{
    public static final AttributeKey<String> UDP_CONNECTIONID_KEY = AttributeKey.valueOf("udp.connectionid"); 
	
    public int port;
    public int portIndex;
    
    public UdpServerHandler(int port,int portIndex) {
    	super("Udp-Server");
    	this.port = port;
    	this.portIndex = portIndex;
	}
    
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
    	super.channelActive(ctx);
    }
    
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
        //获取数据
    	ByteBuf buf = packet.copy().content();
        byte[] data = new byte[buf.readableBytes()];
        buf.getBytes(buf.readerIndex(), data);
        
//        LogUtil.d(new String(data));
        
        //获取地址和端口
        byte[] senderAddressBytes = packet.sender().getAddress().getAddress();
        byte[] senderPortBytes = String.valueOf(packet.sender().getPort()).getBytes();
        
        //拼装并发送
        UdpClient udpClient = UdpClientManager.get(port);
		if(udpClient != null){
			ChannelHandlerContext tunnelCtx = udpClient.getChannelHandlerContext();
//				LogUtil.d("hi:"+hostIndexByte);
			byte portIndexByte = (byte)(portIndex);
        	TunnelDataSenderManager.commitData(TunnelDataSenderManager.UDP_DATA_MSG, tunnelCtx, 
        			//端口序号(占1位)+发送者的地址+分隔符+发送者的端口(占多位)+分隔符+数据
        			new byte[]{portIndexByte},
        			senderAddressBytes, Constant.SPLIT_FLAG_BYTES,
        			senderPortBytes, Constant.SPLIT_FLAG_BYTES,
        			data);
		}
		//对于udpClient==null的情况，不从netty管道返回，就是没消息返回就是了，因为udp并非面向连接
    }
    

    @Override  
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//        LogUtil.d("Udp-Server exception");
        ctx.close();
    }

	@Override
    protected void handleWriterIdle(ChannelHandlerContext ctx) {
//        LogUtil.d("Udp-Server timeout");
        super.handleReaderIdle(ctx);
        ctx.close();
    }
	
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
//        LogUtil.d("Udp-Server closing");
		super.channelInactive(ctx);
//        LogUtil.d("Udp-Server close success");
	}
	
}  